-- 判断table是否为空
local isempty = require("table.isempty")

-- 两个table合并
local function union(t1,t2)
    for k,v in pairs(t2) do
        t1[k] = v
    end
    return t1
end

-- 检验请求的sign签名是否正确
-- params: 传入的参数值组成的table
-- secret: 项目secret,根据key找到secret
local function signcheck(params,secret)
    -- 判断参数是否为空，为空报异常
    if isempty(params) then
        local msg = "参数为空"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    -- 判断参数是否有携带key
    local key = params["key"]
    if key == nil then
        local msg = "key值为空"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    if secret == nil then
        local msg = "私钥为空"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    -- 判断是否有签名参数
    local sign = params["sign"]
    if sign == nil then
        local msg = "参数签名为空"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    -- 判断参数是否携带时间戳
    local timestamp = params["time"]
    if timestamp == nil then
        local msg = "时间戳参数为空"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    -- 判断时间戳有没有过期，3秒为过期
    local now_mill = ngx.now() * 1000 --毫秒级
    ngx.log(ngx.ERR,now_mill .. "  " .. timestamp)
    if now_mill - timestamp > 3000 then
        local msg = "链接过期"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end

    local keys,tmp = {},{}

    -- 提出所有的健名并按字符顺序排序
    for k,_ in pairs(params) do


        if k ~= "sign" then
            keys[#keys+1] = k
        end
    end

    table.sort(keys)
    ngx.log(ngx.ERR,"-----",table.concat(keys,","))
    -- 根据排序好的健名依次读取值并拼接成字符串 key=value&key=value
    for _,k in pairs(keys) do
        if type(params[k]) == "string" or type(params[k]) == "number" then
            tmp[#tmp+1] = k .. "=" .. tostring(params[k])
        end
    end
    -- 将slat（secret）添加到最后，计算正确的签名sign值并与传入的sign签名对比
    local signchar = table.concat(tmp,"&") .. "&" .. secret
    local rightsign = ngx.md5(signchar)
    ngx.log(ngx.ERR,sign,"..."..rightsign)
    if sign ~= rightsign then
        -- 如果签名不匹配则返回错误信息并记录日志
        local msg = "服务端验签失败"
        ngx.log(ngx.ERR,msg)
        return false,msg
    end
    return true
end

local params = {}
local get_args = ngx.req.get_uri_args()
ngx.req.read_body()
local post_args = ngx.req.get_post_args()

union(params,get_args)
union(params,post_args)

-- 根据keyID到后台服务获取secret
local secret = "abc123"
local checkResult,mess = signcheck(params,secret)

if not checkResult then
    ngx.say(mess)
    return ngx.exit(ngx.HTTP_FORBIDDEN)
end